package com.smarthome.common.tools.verify;

import java.lang.reflect.Field;

import org.apache.commons.lang.StringUtils;

import com.smarthome.domain.enums.ResponseCode;
import com.smarthome.domain.enums.RegexType;
import com.smarthome.common.exception.ParamException;
import com.smarthome.common.tools.RegexUtil;

/**
 * VerifyUtil 校验接口参数
 *
 * @author KongXiangyu
 * @since 1.0
 */
public class VerifyUtil {

    private static Verify verify;

    public VerifyUtil() {
        super();
    }

    // 解析的入口
    public static void valid(Object object) throws Exception {
        // 获取object的类型
        Class<? extends Object> clazz = object.getClass();
        // 获取该类型声明的成员
        Field[] fields = clazz.getDeclaredFields();
        // 遍历属性
        for (Field field : fields) {
            // 对于private私有化的成员变量，通过setAccessible来修改器访问权限
            field.setAccessible(true);
            validate(field, object);
            // 重新设置会私有权限
            field.setAccessible(false);
        }
    }

    private static void validate(Field field, Object object) throws Exception {
        String description;
        Object value;
        // 获取对象的成员的注解信息
        verify = field.getAnnotation(Verify.class);
        // 获取字段的值
        value = field.get(object);
        // 没有@Verify注解不验证
        if (verify == null) {
            return;
        }
        // 字段值为空不验证
        if (value == null || StringUtils.isBlank(value.toString())) {
            return;
        }
        // 若未设置description，去字段名称
        description = verify.description().equals("") ? field.getName() : verify.description();
        // 验证最大长度
        if (value.toString().length() > verify.maxLength() && verify.maxLength() != 0) {
            throw new ParamException(ResponseCode.LENGTH_CAN_NOT_MORE_THAN, description, verify.maxLength());
        }
        // 验证最小长度
        if (value.toString().length() < verify.minLength() && verify.minLength() != 0) {
            throw new ParamException(ResponseCode.LENGTH_CAN_NOT_LESS_THAN, description, verify.maxLength());
        }

        if (verify.regexType() != RegexType.NONE) {
            switch (verify.regexType()) {
            case NONE:
                break;
            case SPECIALCHAR:
                if (RegexUtil.hasSpecialChar(value.toString())) {
                    throw new ParamException(ResponseCode.CAN_NOT_CONTAIN_SPECIAL_CHARACTERS, description);
                }
                break;
            case CHINESE:
                if (RegexUtil.isChinese2(value.toString())) {
                    throw new ParamException(ResponseCode.CAN_NOT_CONTAIN_CHINESE, description);
                }
                break;
            case EMAIL:
                if (!RegexUtil.isEmail(value.toString())) {
                    throw new ParamException(ResponseCode.FORMAT_ERROR, "邮箱", "例如smarthome@smarthome.com");
                }
                break;
            case IP:
                if (!RegexUtil.isIp(value.toString())) {
                    throw new ParamException(ResponseCode.FORMAT_ERROR, "IP地址", "例如192.168.1.1");
                }
                break;
            case NUMBER:
                if (!RegexUtil.isNumber(value.toString())) {
                    throw new ParamException(ResponseCode.NUMERIC_TYPE_ERROR, "数字", value.toString());
                }
                break;
            case MONEY:
                if (!RegexUtil.isMoney(value.toString())) {
                    throw new ParamException(ResponseCode.FORMAT_ERROR, description, "金额格式为非负整数");
                }
                break;
            case MOBILE:
                if (!RegexUtil.isMobile(value.toString())) {
                    throw new ParamException(ResponseCode.FORMAT_ERROR, "手机号", "例如13888888888");
                }
                break;
            case NAME:
                if (!RegexUtil.isName(value.toString())) {
                    throw new ParamException(ResponseCode.FORMAT_ERROR, "姓名", "个人为2-12位中文名");
                }
                break;
            case COMPANY_NAME:
                if (!RegexUtil.isCompanyName(value.toString())) {
                    throw new ParamException(ResponseCode.FORMAT_ERROR, "公司名称", "公司为4-32位中文名");
                }
                break;
            case CREDENTIAL_NO:
                if (!RegexUtil.isCredentailNo(value.toString())) {
                    throw new ParamException(ResponseCode.FORMAT_ERROR, "身份证号", "15位或18位身份证号");
                }
                break;
            case BIZ_CODE:
                if (!RegexUtil.isBizCode(value.toString())) {
                    throw new ParamException(ResponseCode.FORMAT_ERROR, "工商注册号", "15位营业执照编号");
                }
                break;
            case VERIFY_CODE:
                if (!RegexUtil.isVerifyCode(value.toString())) {
                    throw new ParamException(ResponseCode.FORMAT_ERROR, "短信验证码", "验证码格式为6位数字");
                }
                break;
            case IMAGE:
                if (!RegexUtil.isImage(value.toString())) {
                    throw new ParamException(ResponseCode.FORMAT_ERROR, description, "应该为jgp,jpeg,bmp,png几种格式的图片");
                }
                break;
            case URL:
                if (!RegexUtil.isUrl(value.toString())) {
                    throw new ParamException(ResponseCode.FORMAT_ERROR, description, "网址");
                }
                break;
            default:
                break;
            }
        }
        // 验证自定义验证规则
        if (!verify.regexExpression().equals("")) {
            if (value.toString().matches(verify.regexExpression())) {
                throw new ParamException(ResponseCode.FORMAT_ERROR, description);
            }
        }
        /************* 注解解析工作结束 ******************/
    }
}
